<template>
  <div class="ek-select">
    <el-tree-select
      v-model="value"
      :data="ekOptions"
      :props="treeConfig.defaultProps"
      :check-strictly="treeConfig.checkStrictly"
      :check-on-click-node="treeConfig.checkOnClickNode"
      :show-checkbox="treeConfig.showCheckbox"
      :node-key="treeConfig.nodeKey"
      :lazy="treeConfig.lazy"
      :load="handleLoad"
      :multiple="multiple"
      filterable
      @blur="blur"
      @focus="focus"
      @change="change"
      @clear="clear"
      :loading="loading"
      loading-text="加载中"
      no-data-text="无数据"
      :placeholder="placeholder"
      :disabled="disabled"
      :clearable="clearable"
      :collapse-tags="collapseTags"
      :remote="remote"
    >
    </el-tree-select>
  </div>
</template>

<script setup>
import {
  defineComponent,
  defineEmits,
  onMounted,
  getCurrentInstance,
  computed,
  ref,
  watch,
  reactive,
} from "vue";
import { arrayToTree } from "@/utils/common";

const props = defineProps({
  modelValue: {
    type: [String, Number, Array, Boolean],
    default: "",
  },
  //选项，选项里面必须包含label和value
  options: {
    type: Array,
    default: () => [],
  },
  // 是否多选
  multiple: {
    type: Boolean,
    default: false,
  },
  // 禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 是否显示清除
  clearable: {
    type: Boolean,
    default: true,
  },
  // 默认显示
  placeholder: {
    type: String,
    default: "请选择",
  },
  // 初始化请求接口
  autoInit: {
    type: Boolean,
    default: false,
  },
  // 搜索开启远程
  remote: {
    type: Boolean,
    default: false,
  },
  // 远程地址,存在远程地址
  url: {
    type: String,
    default: "",
  },
  // 字段映射
  mapping: {
    type: Object,
    default: () => ({
      label: ["label"],
      value: "value",
    }),
  },
  // 是否开启懒加载
  lazy: {
    type: Boolean,
    default: false,
  },
  // 开启树形结构
  treeOn: {
    type: Boolean,
    default: true,
  },
  collapseTags: {
    type: Boolean,
    default: true,
  },
  // 树形配置
  treeConfig: {
    type: Object,
    default: {},
  },
});

const {
  appContext: {
    config: { globalProperties },
  },
} = getCurrentInstance();

const { $http } = globalProperties;

const emit = defineEmits([
  "update:modelValue",
  "blur",
  "focus",
  "change",
  "clear",
]);

const value = computed({
  get() {
    if (props.multiple) {
      return props.modelValue;
    } else {
      return props.modelValue;
    }
  },
  set(value) {
    if (props.multiple) {
      emit("update:modelValue", value);
    } else {
      emit("update:modelValue", value);
    }
  },
});

// 选项列表
const ekOptions =  computed(() => {
  if(props.url){
    return remoteData.value;
  } else {
    return props.options
  }
});
// 加载中
let loading = ref(false);
// 是否已经加载过
let loaded = ref(false);
// 树结构配置
let treeConfig = {
  defaultProps: {
    children: "children",
    label: "label",
    isLeaf: "leaf",
    disabled: "disabled",
    class: "class",
  },
  // 选择任意级别
  checkStrictly: false,
  // 点击节点选中
  checkOnClickNode: false,
  // 是否显示复选框
  showCheckbox: false,
  // 主键
  nodeKey: "id",
  // 开启懒加载
  lazy: false,

  fieldMapping: {
    label: "label",
    id: "id",
    parentId: "parent_id",
  },
  ...props.treeConfig,
};
// 取数据的模型编码

let fieldMapping = treeConfig.fieldMapping;

let url = props.url;

// 获取远程数据
const remoteData = ref([]);

function init(isFocus = false) {
  console.log(value, "valuevaluevalue");
  // 存在远程地址，开启初始化获取数据或者存在值
  if (url) {
    if (isFocus || props.autoInit || value.value || value.value?.length) {
      // 开启树形结构
      if (props.treeOn) {
        // 开启懒加载
        if (treeConfig.lazy) {
          // 懒加载获取数据
          initLazy();
        } else {
          // 一次性获取数据
          getTreeData(url);
        }
      } else {
        // 正常结构
        getData(url);
      }
    }
  } 
}
// 获取下拉列表
function getData(url) {
  if (loaded.value || loading.value) {
    return;
  }
  loading.value = true;
  $http.post(url).then((res) => {
    if (res.status === 'success') {
      if (res.data?.length) {
        remoteData.value = res.data;
      }
      loaded.value = true;
      loading.value = false;
    }
  });
}
init(false);
// 获取下拉列表
function getTreeData(url) {
  if (loaded.value || loading.value) {
    return;
  }
  loading.value = true;
  $http.post(url).then((res) => {
    if (res.status === 'success')  {
      let tree = res.data?.length ? res.data : [];
      if (tree.length) {
        tree = setMappingData(props.mapping, tree);;
        for (let i in fieldMapping) {
          let val = fieldMapping[i];
          for (let j in tree) {
            tree[j][i] = tree[j][val];
          }
        }
      }
      remoteData.value = arrayToTree(tree);
      loaded.value = true;
      loading.value = false;
    }
  });
}
/* 开启懒加载，使用foucs触发懒加载初始化 */
function initLazy() {
  if (loaded.value || loading.value) {
    return;
  }
  loading.value = true;
  $http
    .post(url, {
      type: "lazy",
      parentId: "",
    })
    .then((res) => {
      let tree = res.data?.length ? res.data : [];
      if (tree.length) {
        tree = setMappingData(props.mapping, tree);
        for (let i in fieldMapping) {
          let val = fieldMapping[i];
          for (let j in tree) {
            tree[j][i] = tree[j][val];
          }
        }
      }
      remoteData.value = arrayToTree(tree);
      loaded.value = true;
      loading.value = false;
    });
}
// 懒加载
function handleLoad(node, resolve, reject) {
  // 没有开启自动初始化，且没有加载过，不执行；因为el-tree 初始化会执行该方法
  if (!loaded.value) {
    return;
  }
  $http
    .post(url, {
      type: "lazy",
      parentId: node.data.id,
    })
    .then((res) => {
      let tree = res.data;
      if (tree.length) {
        tree = setMappingData(props.mapping, tree);
        for (let i in fieldMapping) {
          let val = fieldMapping[i];
          for (let j in tree) {
            tree[j][i] = tree[j][val];
          }
        }
      }
      resolve(tree);
    });
}
function setMappingData(mapping, data) {
  console.log(mapping, "mappingmapping");
  for (let j in data) {
    let item = data[j];
    item["value"] = item[mapping["value"]];
    let labelArr = [];
    for (let i in mapping["label"]) {
      labelArr.push(item[mapping["label"][i]]);
    }
    item["label"] = labelArr.join("-");
  }
  return data;
}
// 失去焦点
function blur(event) {
  console.log("blur");
  emit("blur", event);
}
// 聚焦
function focus(event) {
  console.log("focus");
  init(true);
  emit("focus", event);
}
// 改变事件
function change(event) {
  emit("change", event);
}
// 清除事件
function clear() {
  console.log("clear");
  emit("clear");
}

// todo 远程搜索 

// todo 懒加载默认显示问题
</script>

<style scoped lang="scss"></style>
